﻿using System.Windows;
using System.Collections.Generic;
using System.Xml;

namespace SHomeWorkshop.LunarPresentation.Commands
{
    public partial class Command
    {
        /// <summary>
        /// 只方法只应由Command.BraceToRow()的另一个无参数静态方法调用。
        /// 必须保证startIndex和endIndex的正确性。否则会出现未处理异常——且不会提示。
        /// </summary>
        /// <param name="startBrace"></param>
        /// <param name="startIndex"></param>
        /// <param name="endBrace"></param>
        /// <param name="endIndex"></param>
        private static void BraceToRow(Expressions.Brace startBrace, int startIndex, Expressions.Brace endBrace, int endIndex)
        {
            if (startBrace == null || endBrace == null) return;
            if (startBrace.Editor != endBrace.Editor) return;
            if (startBrace.ParentPanel == null || endBrace.ParentPanel == null) return;
            if (startBrace.ParentPanel != endBrace.ParentPanel) return;

            if (startIndex < 0 || endIndex < 0 || startIndex >= endIndex) return;

            Editor editor = startBrace.Editor;
            Expressions.SubPanel parentPanel = startBrace.ParentPanel;

            // 将这两个括弧间的所有公式嵌入一个新“行”中。
            List<Expressions.Expression> exList = new List<Expressions.Expression>();
            for (int i = startIndex + 1; i < endIndex; i++)//两个括弧本身其实不需要放到行中。
            {
                Expressions.Expression ex = startBrace.ParentPanel.BasePanel.Children[i] as Expressions.Expression;
                if (ex != null)
                {
                    exList.Add(ex);
                }
            }

            ModifingItem mi = new ModifingItem() { OldSelectedExID = startBrace.ExID };

            Action actDelEndBrace = new Action(endBrace.ExID,
                endIndex, endBrace.GetType().Name, "DeleteExpression", endBrace.XmlData.OuterXml,
                null, ActionType.Delete, parentPanel.ExID);

            parentPanel.XmlData.RemoveChild(endBrace.XmlData);
            parentPanel.BasePanel.Children.Remove(endBrace);
            mi.Add(actDelEndBrace);

            for (int i = exList.Count - 1; i >= 0; i--)
            {
                Expressions.Expression ex = exList[i];
                Action actDelEx = new Action(ex.ExID,
                    parentPanel.BasePanel.Children.IndexOf(ex),
                    ex.GetType().Name, "DeleteExpression", ex.XmlData.OuterXml, null,
                    ActionType.Delete, parentPanel.ExID);

                parentPanel.XmlData.RemoveChild(ex.XmlData);
                parentPanel.BasePanel.Children.Remove(ex);
                mi.Add(actDelEx);
            }

            Action actDelStartBrace = new Action(startBrace.ExID,
                startIndex, startBrace.GetType().Name, "DeleteExpression", startBrace.XmlData.OuterXml,
                null, ActionType.Delete, parentPanel.ExID);

            parentPanel.XmlData.RemoveChild(startBrace.XmlData);
            parentPanel.BasePanel.Children.Remove(startBrace);
            mi.Add(actDelStartBrace);

            //再插入一个新Row

            XmlNode newRowNode = parentPanel.XmlData.InsertXmlAt(Properties.Resources.Row, startIndex);
            Expressions.Row newRow = new Expressions.Row(startBrace.RootPanel, parentPanel, startBrace.Editor);
            newRow.XmlData = newRowNode;

            //去除默认的文本块。放在这里会出错。
            //newRow.FirstSubPanel.BasePanel.Children.Clear();
            //newRow.FirstSubPanel.XmlData.RemoveAllChildNodes();

            Action actInsertNewRow = new Action(newRow.ExID, startIndex, newRow.GetType().Name,
                "InsertExpression", null, newRow.XmlData.OuterXml, ActionType.Insert, parentPanel.ExID);
            mi.Add(actInsertNewRow);

            for (int i = 0; i < exList.Count; i++)
            {
                Expressions.Expression ex = exList[i];
                newRow.FirstSubPanel.BasePanel.Children.Add(ex);
                ex.ParentPanel = newRow.FirstSubPanel;
                newRow.FirstSubPanel.XmlData.AppendChild(ex.XmlData);

                Action actInsertEx = new Action(ex.ExID, i, ex.GetType().Name, "InsertExpression",
                    null, ex.XmlData.OuterXml, ActionType.Insert, newRow.FirstSubPanel.ExID);

                mi.Add(actInsertEx);
            }

            //删除“行”中默认添加的一个文本块。
            Expressions.Expression defChildEx = newRow.FirstSubPanel.BasePanel.Children[0] as Expressions.Expression;
            if (defChildEx != null)
            {
                Action actDelDefBaseText = new Action(defChildEx.ExID, 0, defChildEx.GetType().Name,
                    "DeleteExpression", defChildEx.XmlData.OuterXml, null, ActionType.Delete,
                    newRow.FirstSubPanel.ExID);
                newRow.FirstSubPanel.BasePanel.Children.Remove(defChildEx);
                newRow.FirstSubPanel.XmlData.RemoveChild(defChildEx.XmlData);
                mi.Add(actDelDefBaseText);
            }

            if (parentPanel.Direction != newRow.Direction)
            {
                Action actDirection = new Action(newRow.ExID, -1, newRow.GetType().Name,
                    "Direction", newRow.Direction.ToString(), parentPanel.Direction.ToString());
                newRow.Direction = parentPanel.Direction;
                mi.Add(actDirection);
            }

            parentPanel.BasePanel.Children.Insert(startIndex, newRow);

            editor.Do(mi);
            editor.IsModified = true;

            editor.SelectedExpression = newRow;
            mi.NewSelectedExID = newRow.ExID;
        }

        public static void BraceToRow()
        {
            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;
            if (Globals.selectedEditor.SelectedExpression.ParentPanel == null) return;

            Editor editor = Globals.selectedEditor;

            Expressions.Brace startBrace = null;
            Expressions.Brace endBrace = null;

            LunarPresentation.Expressions.Brace curBrace = Globals.selectedEditor.SelectedExpression as Expressions.Brace;

            switch (curBrace.Braces)
            {
                case Expressions.Brace.BraceLocation.Start:
                    {
                        startBrace = curBrace;

                        int startIndex = startBrace.ParentPanel.BasePanel.Children.IndexOf(startBrace);
                        int endIndex = -1;

                        for (int i = startIndex + 1; i < startBrace.ParentPanel.BasePanel.Children.Count; i++)
                        {
                            Expressions.Brace b = startBrace.ParentPanel.BasePanel.Children[i] as Expressions.Brace;
                            if (b == null) continue;

                            if (b.Braces == Expressions.Brace.BraceLocation.Start)
                            {
                                //MessageBox.Show("“括弧”不匹配——此功能要求一首一尾两个配对的“括弧”，中间不能存在另一个首括弧。",
                                //    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                //return;
                                continue;
                            }
                            else
                            {
                                endBrace = b;
                                endIndex = i;
                                break;
                            }
                        }

                        if (endBrace == null)
                        {
                            MessageBox.Show("没有找到可配对的“尾括弧”——此功能要求一首一尾两个配对的“括弧”。",
                                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }

                        if (endIndex <= startIndex + 1)
                        {
                            MessageBox.Show("这两个配对的“括弧”之间没有任何其它公式可以嵌入“行”中。",
                                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }

                        BraceToRow(startBrace, startIndex, endBrace, endIndex);
                        break;
                    }
                case Expressions.Brace.BraceLocation.End:
                    {
                        endBrace = curBrace;

                        int endIndex = endBrace.ParentPanel.BasePanel.Children.IndexOf(endBrace);
                        int startIndex = -1;

                        for (int i = endIndex - 1; i >= 0; i--)
                        {
                            Expressions.Brace b = endBrace.ParentPanel.BasePanel.Children[i] as Expressions.Brace;
                            if (b == null) continue;

                            if (b.Braces == Expressions.Brace.BraceLocation.End)
                            {
                                //MessageBox.Show("“括弧”不匹配——此功能要求一首一尾两个配对的“括弧”，中间不能存在另一个尾括弧。",
                                //    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                //return;
                                continue;
                            }
                            else
                            {
                                startBrace = b;//找到匹配的StartBrace
                                startIndex = i;
                                break;
                            }
                        }

                        if (startBrace == null)
                        {
                            MessageBox.Show("没有找到可配对的“首括弧”——此功能要求一首一尾两个配对的“括弧”。",
                                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }

                        if (endIndex <= startIndex + 1)
                        {
                            MessageBox.Show("这两个配对的“括弧”之间没有任何其它公式可以嵌入“行”中。",
                                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }

                        BraceToRow(startBrace, startIndex, endBrace, endIndex);
                        break;
                    }
            }
        }
    }
}
